﻿#ifdef WIN32
#pragma execution_character_set("utf-8")
#endif

#include "DMainViewController.h"

#include <DAddHomeworkView.h>

#include <QMessageBox>
#include <QTextEdit>

#include "DDBController.h"
#include "DQueryController.h"
#include "DQueryParaMgr.h"
#include "DSearchResultItem.h"
#include "DSqliteMgr.h"
#include "DUtils.h"

DMainViewController::DMainViewController(QObject* parent)
    : QObject(parent)
{
    m_addHomeworkView = new DAddHomeworkView();

    connect(m_addHomeworkView, &DAddHomeworkView::signalChangeHomework,
            [this](QDate dt, int id)
            {
                std::vector<DAddHomework> vecAdd = getAddData(dt, id);
                m_addHomeworkView->updateUI(vecAdd);
            });

    connect(m_addHomeworkView, &DAddHomeworkView::signalSubmit, this,
            &DMainViewController::slotSubmit);

    Qt::WindowFlags flags = m_addHomeworkView->windowFlags();
    m_addHomeworkView->setWindowFlags(flags | Qt::Tool);
}

void DMainViewController::onTreeItemChanged(QTreeWidgetItem* item, int column)
{
    int count = item->childCount();

    if (Qt::Checked == item->checkState(0))
    {
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
                item->child(i)->setCheckState(0, Qt::Checked);
        }
    }
    else if (Qt::Unchecked == item->checkState(0))
    {
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
                item->child(i)->setCheckState(0, Qt::Unchecked);
        }
    }
}

void DMainViewController::loadTreeWgt()
{
    QTreeWidget* treeWgt = m_mainWindow->getTreeWgt();
    treeWgt->clear();

    const Qt::ItemFlags itemFlags =
        Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    // subject
    DObjectPtr<DSqliteMgr> sqliteMgr;
    const std::vector<DSubject> vecSubject = sqliteMgr->getAllSubject();
    for (const auto& s : vecSubject)
    {
        QTreeWidgetItem* itemSubject = new QTreeWidgetItem(treeWgt);
        itemSubject->setData(0, Qt::UserRole, (int)DNodeType::Subject);
        itemSubject->setTextColor(0, Qt::blue);
        itemSubject->setText(0, QString::fromStdString(s.strName));
        itemSubject->setFlags(itemFlags);
        itemSubject->setCheckState(0, Qt::Checked);

        // homeworktype
        for (const auto& h : s.vecHomeworkType)
        {
            QTreeWidgetItem* itemHomeworkType =
                new QTreeWidgetItem(itemSubject);
            itemHomeworkType->setTextColor(0, Qt::blue);
            itemHomeworkType->setData(0, Qt::UserRole, (int)h.nID);
            itemHomeworkType->setText(0, QString::fromStdString(h.strName));
            itemHomeworkType->setFlags(itemFlags);
            itemHomeworkType->setCheckState(0, Qt::Checked);
        }

        treeWgt->expandItem(itemSubject);
    }

    // HomeworkStatus
    QTreeWidgetItem* itemHomeworkStatusYes = new QTreeWidgetItem(treeWgt);
    itemHomeworkStatusYes->setData(0, Qt::UserRole,
                                   (int)DNodeType::HomeworkYes);
    itemHomeworkStatusYes->setTextColor(0, Qt::green);
    itemHomeworkStatusYes->setText(0, QString::fromStdString("已交作业"));
    itemHomeworkStatusYes->setFlags(itemFlags);
    itemHomeworkStatusYes->setCheckState(0, Qt::Checked);

    QTreeWidgetItem* itemHomeworkStatusNo = new QTreeWidgetItem(treeWgt);
    itemHomeworkStatusNo->setData(0, Qt::UserRole, (int)DNodeType::HomeworkNo);
    itemHomeworkStatusNo->setTextColor(0, Qt::red);
    itemHomeworkStatusNo->setText(0, QString::fromStdString("未交作业"));
    itemHomeworkStatusNo->setFlags(itemFlags);
    itemHomeworkStatusNo->setCheckState(0, Qt::Checked);

    // student
    QTreeWidgetItem* itemStudentRoot = new QTreeWidgetItem(treeWgt);
    itemStudentRoot->setData(0, Qt::UserRole, (int)DNodeType::Student);
    itemStudentRoot->setText(0, QString::fromStdString("学生"));
    itemStudentRoot->setFlags(itemFlags);
    itemStudentRoot->setCheckState(0, Qt::Checked);

    const std::vector<DStudent> vecStudent = sqliteMgr->getAllStudent();
    for (const auto& s : vecStudent)
    {
        QTreeWidgetItem* itemStudent = new QTreeWidgetItem(itemStudentRoot);
        itemStudent->setData(0, Qt::UserRole, (int)s.nID);
        itemStudent->setText(0, QString::fromStdString(s.toDesc()));
        itemStudent->setFlags(itemFlags);
        itemStudent->setCheckState(0, Qt::Checked);
    }

    treeWgt->expandItem(itemStudentRoot);
}

void DMainViewController::showHomeworkDetail(DUIHomeworkItem item)
{
    QString str;
    for (auto submit : item.vecSubmitAll)
    {
        if ((item.bYes && submit.bSubmit) || (item.bNo && !submit.bSubmit))
        {
            str += QString("%1 %2 %3\n")
                       .arg(submit.dtSubmit.toString("yyyy-MM-dd"))
                       .arg(submit.strHomeworkTypName)
                       .arg(submit.bSubmit ? "已交" : "未交");
        }
    }

    QTextEdit* edtData = new QTextEdit();
    edtData->setReadOnly(true);

    QHBoxLayout* layout = new QHBoxLayout();
    layout->setMargin(0);
    layout->addWidget(edtData);
    edtData->setPlainText(str);

    QDialog* dlg = new QDialog();
    dlg->resize(300, 600);
    dlg->setWindowFlags(Qt::WindowCloseButtonHint);
    dlg->setWindowTitle("详细信息");
    dlg->setAttribute(Qt::WA_DeleteOnClose, true);
    dlg->setLayout(layout);
    dlg->exec();
}

std::vector<DAddHomework> DMainViewController::getAddData(const QDate& dt,
                                                          IDHomeworkType type)
{
    DObjectPtr<DSqliteMgr> sqliteMgr;

    const std::vector<DStudent>& vecStudent = sqliteMgr->getAllStudent();

    // init date
    std::vector<DAddHomework> vecAdd;
    for (const auto& student : vecStudent)
    {
        DAddHomework add;
        add.student = student;

        const std::vector<DUISubmit> vecSubmit =
            sqliteMgr->getSubmitYesNoData(student.nID, dt, dt, type);

        if (vecSubmit.size() > 0)
        {
            add.bYes = vecSubmit[0].bSubmit;
        }

        vecAdd.push_back(add);
    }

    return vecAdd;
}

void DMainViewController::slotSubmit(QDate dt, IDHomeworkType type,
                                     std::vector<DAddHomework> vecAdd)
{
    qInfo() << dt << type << vecAdd.size();

    DObjectPtr<DSqliteMgr> sqliteMgr;
    sqliteMgr->submit(dt, type, vecAdd);

    QMessageBox::information(m_addHomeworkView, "提示", "录入成功!");
}

void DMainViewController::slotQuery()
{
    DObjectPtr<DQueryParaMgr> queryMgr;

    auto [s, k] = m_mainWindow->getDate();
    if (s > k)
    {
        QMessageBox::information(m_mainWindow, "提示", "日期范围错误!");
        return;
    }
    queryMgr->setDate(s, k);

    std::vector<int> vecTmp;

    // write data to mgr
    const std::vector<QTreeWidgetItem*> vecHomeworkType =
        m_mainWindow->getItems(DNodeType::Subject, true);
    vecTmp.clear();
    for (const auto& item : vecHomeworkType)
    {
        if (Qt::Checked == item->checkState(0))
        {
            QVariant v = item->data(0, Qt::UserRole);
            vecTmp.push_back(v.toInt());
        }
    }
    queryMgr->setHomeworkTypeID(vecTmp);

    const std::vector<QTreeWidgetItem*> vecStudent =
        m_mainWindow->getItems(DNodeType::Student, true);
    vecTmp.clear();
    for (const auto& item : vecStudent)
    {
        if (Qt::Checked == item->checkState(0))
        {
            vecTmp.push_back(item->data(0, Qt::UserRole).toInt());
        }
    }
    queryMgr->setStudentID(vecTmp);

    const std::vector<QTreeWidgetItem*> vecYes =
        m_mainWindow->getItems(DNodeType::HomeworkYes, false);

    const std::vector<QTreeWidgetItem*> vecNo =
        m_mainWindow->getItems(DNodeType::HomeworkNo, false);

    const std::vector<QTreeWidgetItem*> vecYesNo = {vecYes.front(),
                                                    vecNo.front()};
    vecTmp.clear();
    for (const auto& item : vecYesNo)
    {
        if (Qt::Checked == item->checkState(0))
        {
            vecTmp.push_back(item->data(0, Qt::UserRole).toInt());
        }
    }

    queryMgr->setHomeworkStatus(vecTmp);

    // query
    DQueryController queryController;

    const std::vector<DUIHomeworkItem> vecResult = queryController.query();

    QVBoxLayout* layoutContent = m_mainWindow->getContent();
    DUtils::clearLayout(layoutContent);

    constexpr int COLUMNCOUNT = 5;
    for (int i = 0; i < std::ceil(vecResult.size() * 1.0 / COLUMNCOUNT); ++i)
    {
        QHBoxLayout* layoutRow = new QHBoxLayout();
        for (int j = 0; j < COLUMNCOUNT; ++j)
        {
            const int nIndex = i * COLUMNCOUNT + j;
            if (nIndex < vecResult.size())
            {
                DSearchResultItem* item =
                    new DSearchResultItem(vecResult[nIndex]);
                layoutRow->addWidget(item);

                connect(item, &DSearchResultItem::signalDetail,
                        [this](DUIHomeworkItem item)
                        { showHomeworkDetail(item); });
            }
        }
        layoutRow->addStretch();
        layoutContent->addLayout(layoutRow);
    }

    layoutContent->addStretch();
}

void DMainViewController::slotAdd()
{
    DObjectPtr<DSqliteMgr> sqliteMgr;

    const QDate dt = QDate::currentDate();
    const std::vector<DHomeworkType> vecType = sqliteMgr->getAllHomework();
    IDHomeworkType type = vecType.front().nID;

    std::vector<DAddHomework> vecAdd = getAddData(dt, type);
    m_addHomeworkView->initUI(vecAdd, dt, vecType, type);
    m_addHomeworkView->exec();
}

void DMainViewController::slotFresh() {}
